package com.ruoyi.user.service.impl;

import com.ruoyi.user.domain.UserOrderDetail;
import com.ruoyi.user.domain.UserOrderItems;
import com.ruoyi.user.domain.UserOrderReview;
import com.ruoyi.user.domain.UserOrders;
import com.ruoyi.user.domain.vo.OrderItemRequest;
import com.ruoyi.user.domain.vo.OrderSubmitRequest;
import com.ruoyi.user.domain.vo.OrderListItemVO;
import com.ruoyi.user.domain.vo.OrderListProductVO;
import com.ruoyi.user.mapper.UserOrderItemsMapper;
import com.ruoyi.user.mapper.UserOrderReviewsMapper;
import com.ruoyi.user.mapper.UserOrdersMapper;
import com.ruoyi.user.service.IUserOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class UserOrdersServiceImpl implements IUserOrdersService {

    @Autowired
    private UserOrdersMapper ordersMapper;
    @Autowired
    private UserOrderItemsMapper orderItemsMapper;
    @Autowired
    private UserOrderReviewsMapper orderReviewsMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long submitOrder(OrderSubmitRequest request) {
        if (request == null || request.getItems() == null || request.getItems().isEmpty()) {
            throw new IllegalArgumentException("订单提交失败：商品明细不能为空");
        }

        BigDecimal total = BigDecimal.ZERO;
        Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

        for (OrderItemRequest item : request.getItems()) {
            if (item.getQuantity() == null || item.getQuantity() <= 0) {
                throw new IllegalArgumentException("订单提交失败：商品数量必须大于0");
            }
            BigDecimal unit = item.getUnitPrice() == null ? BigDecimal.ZERO : item.getUnitPrice();
            BigDecimal line = unit.multiply(BigDecimal.valueOf(item.getQuantity()));
            total = total.add(line);
        }

        BigDecimal discount = BigDecimal.ZERO;
        BigDecimal subsidy = BigDecimal.ZERO;
        BigDecimal finalAmount = total.subtract(discount).subtract(subsidy);
        if (finalAmount.compareTo(BigDecimal.ZERO) < 0) {
            finalAmount = BigDecimal.ZERO;
        }

        UserOrders order = new UserOrders();
        order.setOrderNo(genOrderNo());
        order.setCustomerId(request.getCustomerId());
        order.setMerchantId(request.getMerchantId());
        order.setMerchantName(request.getMerchantName());
        order.setRegionId(request.getRegionId());
        order.setPickupCode(genPickupCode());
        order.setStatus(0);
        order.setTotalAmount(total);
        order.setDiscountAmount(discount);
        order.setRegionSubsidy(subsidy);
        order.setFinalAmount(finalAmount);
        order.setPaymentMethod(request.getPaymentMethod());
        order.setPaymentStatus(0);
        order.setAddressSnapshot(request.getAddressSnapshot());
        order.setRemark(request.getRemark());
        order.setTablewareCount(request.getTablewareCount() == null ? 1 : request.getTablewareCount());
        order.setEstimatedReadyMin(null);
        order.setCreatedAt(now);
        order.setUpdatedAt(now);

        ordersMapper.insertOrders(order);

        Long orderId = order.getOrderId();
        List<UserOrderItems> toInsert = new ArrayList<>();
        for (OrderItemRequest r : request.getItems()) {
            BigDecimal unit = r.getUnitPrice() == null ? BigDecimal.ZERO : r.getUnitPrice();
            BigDecimal line = unit.multiply(BigDecimal.valueOf(r.getQuantity()));

            UserOrderItems oi = new UserOrderItems();
            oi.setOrderId(orderId);
            oi.setProductId(r.getProductId());
            oi.setProductName(r.getProductName());
            oi.setProductImage(r.getProductImage());
            oi.setQuantity(r.getQuantity());
            oi.setUnitPrice(unit);
            oi.setTasteOptions(r.getTasteOptions());
            oi.setTotalPrice(line);
            oi.setCreatedAt(now);
            toInsert.add(oi);
        }

        for (UserOrderItems oi : toInsert) {
            orderItemsMapper.insertOrderItems(oi);
        }

        return orderId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean payOrder(Long orderId, Integer paymentMethod) {
        UserOrders existing = ordersMapper.selectOrdersByOrderId(orderId);
        if (existing == null) {
            throw new IllegalArgumentException("订单不存在");
        }
        if (existing.getPaymentStatus() != null && existing.getPaymentStatus() == 1) {
            return true; // 已支付
        }

        Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
        UserOrders upd = new UserOrders();
        upd.setOrderId(orderId);
        upd.setPaymentMethod(paymentMethod);
        upd.setPaymentStatus(1);
        upd.setPaidAt(now);
        upd.setUpdatedAt(now);

        // 余额支付扣减逻辑可在此扩展（查询用户余额并扣费），此处略过实际扣费

        return ordersMapper.updateOrders(upd) > 0;
    }

    @Override
    public List<UserOrders> listOrdersByCustomer(Long customerId) {
        UserOrders q = new UserOrders();
        q.setCustomerId(customerId);
        return ordersMapper.selectOrdersList(q);
    }

    @Override
    public List<UserOrders> listOrdersByStatus(Long customerId, Integer status) {
        UserOrders q = new UserOrders();
        q.setCustomerId(customerId);
        q.setStatus(status);
        return ordersMapper.selectOrdersList(q);
    }

    @Override
    public List<OrderListItemVO> listOrderSummariesByCustomer(Long customerId) {
        List<OrderListItemVO> list = ordersMapper.selectOrderSummariesByCustomerId(customerId);
        for (OrderListItemVO o : list) {
            List<UserOrderItems> items = orderItemsMapper.selectOrderItemsByOrderId(o.getOrderId());
            List<OrderListProductVO> ps = new ArrayList<>();
            int total = 0;
            for (UserOrderItems it : items) {
                OrderListProductVO p = new OrderListProductVO();
                p.setProductName(it.getProductName());
                p.setProductImage(it.getProductImage());
                p.setQuantity(it.getQuantity());
                ps.add(p);
                total += it.getQuantity() == null ? 0 : it.getQuantity();
            }
            o.setItems(ps);
            o.setTotalQuantity(total);
        }
        return list;
    }

    @Override
    public List<OrderListItemVO> listOrderSummariesByStatus(Long customerId, Integer status) {
        List<OrderListItemVO> list = ordersMapper.selectOrderSummariesByStatus(customerId, status);
        for (OrderListItemVO o : list) {
            List<UserOrderItems> items = orderItemsMapper.selectOrderItemsByOrderId(o.getOrderId());
            List<OrderListProductVO> ps = new ArrayList<>();
            int total = 0;
            for (UserOrderItems it : items) {
                OrderListProductVO p = new OrderListProductVO();
                p.setProductName(it.getProductName());
                p.setProductImage(it.getProductImage());
                p.setQuantity(it.getQuantity());
                ps.add(p);
                total += it.getQuantity() == null ? 0 : it.getQuantity();
            }
            o.setItems(ps);
            o.setTotalQuantity(total);
        }
        return list;
    }

    @Override
    public UserOrderDetail getOrderDetail(Long orderId) {
        UserOrders order = ordersMapper.selectOrdersByOrderId(orderId);
        if (order == null) {
            return null;
        }
        List<UserOrderItems> items = orderItemsMapper.selectOrderItemsByOrderId(orderId);
        UserOrderDetail detail = new UserOrderDetail();
        detail.setOrder(order);
        detail.setItems(items);
        return detail;
    }

    @Override
    public int addOrderReview(UserOrderReview review) {
        Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
        review.setCreatedAt(now);
        review.setUpdatedAt(now);
        return orderReviewsMapper.insertOrderReview(review);
    }

    @Override
    public int countOrdersByMerchantLastMonth(Long merchantId) {
        return ordersMapper.countOrdersByMerchantLastMonth(merchantId);
    }

    private String genOrderNo() {
        String raw = UUID.randomUUID().toString().replaceAll("-", "");
        return raw.length() > 32 ? raw.substring(0, 32) : raw;
    }

    private String genPickupCode() {
        int code = (int)(Math.random() * 9000) + 1000;
        return String.valueOf(code);
    }
}
